from fastapi import APIRouter
from pydantic import BaseModel
from tortoise.expressions import Q
from log.logger import setup_logger
from spark.analyze_models import frequency_analysis, gender_analysis, water_army_analysis, analyzed_room
from spark.models import ChatMessage, FansclubMessage, GiftMessage, LikeMessage, MemberMessage, RoomUserSeqMessage, SocialMessage
from utils import chat_ai
from datetime import datetime, timedelta
from collections import defaultdict


# 创建全局logger
logger = setup_logger()


init = APIRouter()

# 定义请求体的数据模型


class ChatData(BaseModel):
    room_id: str
    analyze_time: str
    message: str


async def all_table_list(room_id, create_time_str):
    # 将字符串日期转换为datetime对象
    create_time = datetime.strptime(create_time_str, "%Y-%m-%d")

    # 计算当天结束时间
    end_of_day = create_time + timedelta(days=1)

    # 使用Q对象构建查询条件
    query = Q(room_id=room_id, create_time__range=(create_time, end_of_day))

    chat_count = await ChatMessage.filter(query).count()
    gift_count = await GiftMessage.filter(query).count()
    like_count = await LikeMessage.filter(query).count()
    member_count = await MemberMessage.filter(query).count()
    social_count = await SocialMessage.filter(query).count()
    # 创建包含计数的字典
    room_ids_counts = {
        'all': chat_count + gift_count + like_count + member_count + social_count,
        'chat': chat_count,
        'gift': gift_count,
        'like': like_count,
        'member': member_count,
        'social': social_count
    }

    return room_ids_counts


async def hour_heat_list(room_id, analyze_time):
    # 查看frequency_analysis表中满足room_id，create_time_str的所有数据
    query = Q(room_id=room_id, analyze_time=analyze_time)
    frequency_list = await frequency_analysis.filter(query).values()

    # 使用字典存储每个analyzed_table的最新数据
    latest_data = {}
    for item in frequency_list:
        analyzed_table = item["analyzed_table"]
        create_time = datetime.strptime(item["create_time"], "%Y-%m-%d %H:%M")
        if analyzed_table not in latest_data or create_time > datetime.strptime(latest_data[analyzed_table]["create_time"], "%Y-%m-%d %H:%M"):
            latest_data[analyzed_table] = item

    # 提取analyzed_table和frequency字段
    result = [{"analyzed_table": data["analyzed_table"],
               "frequency": data["frequency"]} for data in latest_data.values()]

    heat_list = []

    # 将数据转换为前端需要的格式，提取hour和value字段
    for item in result:
        analyzed_table = item["analyzed_table"]
        frequency_values = item["frequency"].split(',')
        for hour, value in enumerate(frequency_values):
            value = int(value)
            if value != 0:
                heat_list.append(
                    {"hour": f"{hour}点", "type": analyzed_table, "value": value})

    converted_data = [
        ["hour", "type", "value"]
    ]

    # 遍历原始列表并将每个字典的值转换为嵌套列表
    for item in heat_list:
        converted_data.append([item["hour"], item["type"], item["value"]])

    return converted_data


async def hour_fanclub_list(room_id: int, analyze_time: str):
    # 将字符串日期转换为datetime对象
    create_time = datetime.strptime(analyze_time, "%Y-%m-%d")

    # 计算当天结束时间
    end_of_day = create_time + timedelta(days=1)

    # 使用Q对象构建查询条件
    query = Q(room_id=room_id, create_time__range=(create_time, end_of_day))
    # 查询FansclubMessage表中在指定时间范围内的数据
    fansclub_list = await FansclubMessage.filter(query).values("create_time")

    # 初始化一个字典来统计每个小时的数据量
    hour_count = defaultdict(int)

    # 遍历查询结果，统计每个小时的数据量
    for message in fansclub_list:
        message_time = datetime.strptime(
            message["create_time"], "%Y-%m-%d %H:%M:%S")
        hour = message_time.hour
        hour_count[hour] += 1

    # 构建返回结果
    result = [["hour", "type", "value"]]
    for hour, count in sorted(hour_count.items()):
        if count > 0:
            result.append([f"{hour}点", "FansclubMessage", count])

    return result


async def water_percent_list(room_id: int, analyze_time: str):
    # 查看water_army_analysis表中满足room_id，create_time_str的所有数据
    query = Q(room_id=room_id, analyze_time=analyze_time)
    water_army_list = await water_army_analysis.filter(query).values()

    # 创建一个字典来存储user_name对应的最大all_count行数据
    user_data = {}
    for row in water_army_list:
        user_name = row['user_name']
        if user_name not in user_data:
            user_data[user_name] = row
        else:
            if row['all_count'] > user_data[user_name]['all_count']:
                user_data[user_name] = row

    # 计算重复user_name的平均值
    final_list = []
    for user_name, data in user_data.items():
        count = sum(
            1 for row in water_army_list if row['user_name'] == user_name)
        if count > 1:
            data['chat_count'] = int(data['chat_count'] / count)
            data['like_count'] = int(data['like_count'] / count)
            data['enter_count'] = int(data['enter_count'] / count)
            data['all_count'] = int(data['all_count'] / count)
        final_list.append(data)

    # 根据all_count降序排序
    final_list.sort(key=lambda x: x['all_count'], reverse=True)

    # 过滤掉all_count小于100的行
    final_list = [data for data in final_list if data['all_count'] >= 100]

    # 将字符串日期转换为datetime对象
    create_time = datetime.strptime(analyze_time, "%Y-%m-%d")

    # 计算当天结束时间
    end_of_day = create_time + timedelta(days=1)

    # 使用Q对象构建查询条件
    query = Q(room_id=room_id, create_time__range=(create_time, end_of_day))

    # 查询FansclubMessage表中在指定时间范围内的数据
    online_list = await RoomUserSeqMessage.filter(query).values("create_time", "current")

    # 计算步长
    total_count = len(online_list)
    if total_count < 150:
        step = 1
    else:
        step = max(1, total_count // 100)

    # 构建返回结果
    result = [["hour", "type", "value"]]
    for i in range(0, total_count, step):
        message = online_list[i]
        message_time = datetime.strptime(
            message["create_time"], "%Y-%m-%d %H:%M:%S")
        hour = message_time.strftime("%H:%M")
        result.append([f"{hour}", "RoomUserSeqMessage", message["current"]])

    # 从final_list中得到有多少行数据，将行数赋值给water_army_count
    water_army_count = len(final_list)

    # 从result中的value列得到最大值赋值给online_count
    online_count = max(row[2] for row in result[1:])

    # online_count减去water_army_count得到的值赋值给normal_count
    normal_count = online_count - water_army_count

    # 返回结果
    data = [
        {"value": normal_count, "name": '正常用户'},
        {"value": water_army_count, "name": '网络水军'}
    ]
    return data


async def gender_all_list(room_id, analyze_time):
    # 将字符串日期转换为datetime对象
    create_time = datetime.strptime(analyze_time, "%Y-%m-%d")

    # 计算当天结束时间
    end_of_day = create_time + timedelta(days=1)

    # 使用Q对象构建查询条件
    query = Q(room_id=room_id, create_time__range=(create_time, end_of_day))

    chat_count = await ChatMessage.filter(query).count()
    gift_count = await GiftMessage.filter(query).count()
    like_count = await LikeMessage.filter(query).count()
    member_count = await MemberMessage.filter(query).count()
    social_count = await SocialMessage.filter(query).count()
    # 创建包含计数的字典
    room_ids_counts = {
        'ChatMessage': chat_count,
        'GiftMessage': gift_count,
        'LikeMessage': like_count,
        'MemberMessage': member_count,
        'SocialMessage': social_count
    }

    # 查看frequency_analysis表中满足room_id，create_time_str的所有数据
    query = Q(room_id=room_id, analyze_time=analyze_time)
    gender_list = await gender_analysis.filter(query).values()

    # 创建包含性别分析结果的字典列表
    gender_analysis_list = []
    for gender_data in gender_list:
        table = gender_data['analyzed_table']
        male_count = gender_data['male'] or 1
        woman_count = gender_data['woman'] or 1
        total_count = male_count + woman_count
        if table in room_ids_counts:
            gender_analysis_list.append({
                'table': table,
                'male': int(male_count / total_count * room_ids_counts[table]),
                'woman': int(woman_count / total_count * room_ids_counts[table]),
            })

    # 定义映射关系
    table_mapping = {
        "ChatMessage": "聊天占比",
        "GiftMessage": "礼物占比",
        "LikeMessage": "点赞占比",
        "MemberMessage": "进入占比",
        "SocialMessage": "关注占比"
    }

    # 转换数据
    converted_data = []
    for item in gender_analysis_list:
        converted_data.append({
            "table": table_mapping[item["table"]],
            "male": item["male"],
            "woman": item["woman"]
        })

    return converted_data


@init.get("/room/list")
async def get_room_list():
    # 得到room_id字段列表
    room_list = await analyzed_room.all().values_list('room_id', flat=True)
    room_list = list(set(room_list))  # 对room_list进行去重
    list_dict = list()
    for item in room_list:
        room_dict = dict()
        room_dict['value'] = item
        room_dict['label'] = item
        list_dict.append(room_dict)
    return list_dict


@init.get("/date/list")
async def get_analyzed_date_list(room_id):
    # 得到room_id字段列表
    date_list = await analyzed_room.filter(room_id=room_id).values_list('analyzed_date', flat=True)
    list_dict = list()
    for item in date_list:
        date_dict = dict()
        date_dict['value'] = item
        date_dict['label'] = item
        list_dict.append(date_dict)
    return list_dict


@init.post("/chat/api")
async def chat_data_api(chat_data: ChatData):
    source_data = dict()
    source_data['直播间ID'] = chat_data.room_id
    source_data['直播日期'] = chat_data.analyze_time
    room_ids_counts = await all_table_list(chat_data.room_id, chat_data.analyze_time)
    source_data['所有消息的总数'] = room_ids_counts['all']
    source_data['聊天消息数量'] = room_ids_counts['chat']
    source_data['礼物消息数量'] = room_ids_counts['gift']
    source_data['点赞消息数量'] = room_ids_counts['like']
    source_data['进入消息数量'] = room_ids_counts['member']
    source_data['关注消息数量'] = room_ids_counts['social']
    # 查询各个时段的消息数量
    heat_list = await hour_heat_list(chat_data.room_id, chat_data.analyze_time)
    source_data['各个时段的消息数量'] = heat_list
    # 查询各个新增粉丝团的消息数量
    fansclub_list = await hour_fanclub_list(chat_data.room_id, chat_data.analyze_time)
    source_data['各个新增粉丝团的消息数量'] = fansclub_list
    # 查询网络水军和正常用户的消息数量
    water_list = await water_percent_list(chat_data.room_id, chat_data.analyze_time)
    source_data['网络水军和正常用户的消息数量'] = water_list
    # 查询各个类消息的男女人数
    gender_list = await gender_all_list(chat_data.room_id, chat_data.analyze_time)
    source_data['各个类消息的男女人数'] = gender_list

    # 调用chat_ai.send_with_data方法
    user_text = chat_data.message
    response = chat_ai.send_with_data(user_text, source_data)
    reply = {
        'message': response
    }
    return reply
